home *** CD-ROM | disk | FTP | other *** search
- /* ----------------------------------------------------------------
- * testbtdel.c --
- * B-tree test code.
- * ----------------------------------------------------------------
- */
-
- #include "fmgr.h" /* for M_STATIC/M_DYNAMIC */
-
- #include <stdio.h>
-
- #include "c.h"
-
- #include "attnum.h"
- #include "attval.h"
- #include "bufmgr.h"
- #include "catname.h"
- #include "datum.h"
- #include "log.h"
- #include "genam.h"
- #include "heapam.h"
- #include "itemptr.h"
- #include "istrat.h"
- #include "itup.h"
- #include "name.h"
- #include "oid.h"
- #include "portal.h"
- #include "sdir.h"
- #include "tqual.h"
- #include "valid.h"
- #include "xcxt.h"
-
- #include "btree.h"
-
- RcsId("$Header: /private/postgres/src/test/RCS/testbtdel.c,v 1.10 1992/03/04 14:10:35 hong Exp $");
-
- /* ----------------
- * constants
- * ----------------
- */
-
- #define UninitializedQualification 0
- #define SingleQualification 1
- #define DoubleQualification 2
- #define MarkedQualification 3
-
- #define MarkedTuplesToProcess 64
-
- static int QualificationState;
- ScanKeyEntryData QualificationKeyData[2];
-
- AttributeNumber indexAttrNumber;
- ObjectId indexAttrClass;
-
- /* ----------------------------------------------------------------
- * misc functions
- * ----------------------------------------------------------------
- */
-
- /* ----------------
- * DoCreateIndex
- * ----------------
- */
-
- void
- DoCreateIndex(heapName, indexName, attribute, cls)
- Name heapName;
- Name indexName;
- AttributeNumber attribute;
- ObjectId cls;
- {
- AttributeNumber attributeNumber[1];
- ObjectId attributeClass[1];
-
- elog(NOTICE, "DoCreateIndex... start");
-
- attributeNumber[0] = attribute;
- attributeClass[0] = cls;
-
- /*
- startmmgr(M_STATIC); /* M_DYNAMIC is buggy */
-
- RelationNameCreateIndexRelation(heapName,
- indexName,
- 400 /* B-tree AM */,
- 1,
- attributeNumber,
- attributeClass,
- 0,
- (Datum *) NULL);
- /*
- endmmgr(NULL);
- */
-
- elog(NOTICE, "DoCreateIndex... end");
-
- }
-
- /* ----------------
- * ShowResult
- * ----------------
- */
-
- void
- ShowResult(result, heapRelation)
- GeneralRetrieveIndexResult result;
- Relation heapRelation;
- {
- ItemPointer pointer;
-
- Assert(GeneralRetrieveIndexResultIsValid(result));
-
- pointer = GeneralRetrieveIndexResultGetHeapItemPointer(result);
-
- printf("\t");
-
- if (!ItemPointerIsValid(pointer)) {
- printf("<invalid>\n");
- } else {
- HeapTuple tuple;
- Buffer buffer;
-
- printf("[b,p,o %d, %d, %3d] ",
- ItemPointerGetBlockNumber(pointer),
- ItemPointerSimpleGetPageNumber(pointer),
- ItemPointerSimpleGetOffsetNumber(pointer));
-
- tuple =
- RelationGetHeapTupleByItemPointer(heapRelation,
- NowTimeQual,
- pointer,
- &buffer);
-
- if (!HeapTupleIsValid(tuple)) {
- printf("*NULL*\n");
-
- } else {
- TupleDescriptor descriptor;
- AttributeValue value;
- Boolean valueIsNull;
-
- descriptor = RelationGetTupleDescriptor(heapRelation);
-
- /* may want to print more than just the index attribute, here */
- value =
- HeapTupleGetAttributeValue(tuple,
- buffer,
- indexAttrNumber,
- descriptor,
- &valueIsNull);
-
- if (valueIsNull) {
- printf("<NULL>\n");
- } else {
- printf("<0x%x(%d)>\n",
- DatumGetObjectId(value),
- DatumGetObjectId(value));
- }
-
- ReleaseBuffer(buffer);
- }
- }
- }
-
- /* ----------------
- * ShowScanKeyEntry
- * ----------------
- */
-
- void
- ShowScanKeyEntry(entry)
- ScanKeyEntry entry;
- {
- printf("Qualification is procedure 0x%x(%d) for %d with 0x%x\n",
- entry->procedure,
- entry->procedure,
- DatumGetObjectId(entry->argument),
- entry->flags);
- }
-
- /* ----------------------------------------------------------------
- * browse functions
- * ----------------------------------------------------------------
- */
-
- /* ----------------
- * DoBTreeBrowse
- * ----------------
- */
-
- /*ARGSUSED*/
- void
- DoBTreeBrowse(indexRelation, heapRelation)
- Relation indexRelation;
- Relation heapRelation;
- {
- BTreeNode node;
- BlockNumber blockNumber;
- PageNumber pageNumber;
- OffsetIndex off;
- int cnt;
-
- puts("\n--- BTree Browse ---");
- puts("at the prompt, enter a block number and a page number");
- puts("separated by a space or \".\" alone to end\n");
-
- forever {
- forever {
- Puts("browse> ");
- fflush(stdout);
-
- cnt = scanf("%d %d", &blockNumber, &pageNumber);
- if (cnt != 2) {
- puts("\n--- ending BTree Browse ---");
- fseek(stdin, 0, 2);
- break;
- }
-
- node = RelationFormBTreeNode(indexRelation, blockNumber, pageNumber);
- DumpBTreeNode(node);
- BTreeNodeFree(node);
- putchar('\n');
- }
-
- Puts("Enter offset number: ");
- cnt = scanf("%hd", &off);
- if (cnt != 1) {
- puts("\n--- no more deletion ---");
- fseek(stdin, 0, 2);
- break;
- }
-
- /* do it */
- BTreeIndexTupleDelete(node, off);
- }
- }
-
- /* ----------------------------------------------------------------
- * scan functions
- * ----------------------------------------------------------------
- */
-
- /* ----------------
- * DoForwardScan
- * ----------------
- */
-
- void
- DoForwardScan(indexRelation, heapRelation)
- Relation indexRelation;
- Relation heapRelation;
- {
- IndexScan scan;
- GeneralRetrieveIndexResult result;
-
- puts("A complete forward scan of the index reveals...");
-
- scan = RelationGetIndexScan(indexRelation, 0, 0, (ScanKey) NULL);
- while (result = IndexScanGetGeneralRetrieveIndexResult(scan, 0),
- GeneralRetrieveIndexResultIsValid(result))
- {
- ShowResult(result, heapRelation);
- }
- IndexScanEnd(scan);
- }
-
- /* ----------------
- * DoBackwardScan
- * ----------------
- */
-
- void
- DoBackwardScan(indexRelation, heapRelation)
- Relation indexRelation;
- Relation heapRelation;
- {
- IndexScan scan;
- GeneralRetrieveIndexResult result;
-
- puts("A complete reverse scan of the index reveals...");
-
- scan = RelationGetIndexScan(indexRelation, -1, 0, (ScanKey) NULL);
- while (result = IndexScanGetGeneralRetrieveIndexResult(scan, 1),
- GeneralRetrieveIndexResultIsValid(result))
- {
- ShowResult(result, heapRelation);
- }
- IndexScanEnd(scan);
- }
-
-
- /* ----------------
- * DoSingleQualification
- * ----------------
- */
-
- void
- DoSingleQualification(indexRelation, heapRelation, entry)
- Relation indexRelation;
- Relation heapRelation;
- ScanKeyEntry entry;
- {
- IndexScan scan;
- GeneralRetrieveIndexResult result;
-
- QualificationKeyData[0] = *entry;
-
- ShowScanKeyEntry(&QualificationKeyData[0]);
- puts("A SingleQual scan of the index reveals...");
-
- scan = RelationGetIndexScan(indexRelation, 0, 1,
- (ScanKey)QualificationKeyData);
- while (result = IndexScanGetGeneralRetrieveIndexResult(scan, 0),
- GeneralRetrieveIndexResultIsValid(result))
- {
- ShowResult(result, heapRelation);
- }
- IndexScanEnd(scan);
- }
-
-
- /* ----------------
- * DoDoubleQualification
- * ----------------
- */
-
- void
- DoDoubleQualification(indexRelation, heapRelation, entry)
- Relation indexRelation;
- Relation heapRelation;
- ScanKeyEntry entry;
- {
- IndexScan scan;
- GeneralRetrieveIndexResult result;
-
- QualificationKeyData[1] = *entry;
-
- ShowScanKeyEntry(&QualificationKeyData[0]);
- ShowScanKeyEntry(&QualificationKeyData[1]);
- puts("A DoubleQual scan of the index reveals...");
-
- scan = RelationGetIndexScan(indexRelation, 0, 2,
- (ScanKey)QualificationKeyData);
- while (result = IndexScanGetGeneralRetrieveIndexResult(scan, 0),
- GeneralRetrieveIndexResultIsValid(result))
- {
- ShowResult(result, heapRelation);
- }
- IndexScanEnd(scan);
- }
-
- /* ----------------
- * DoMarkedQualification
- * ----------------
- */
-
- void
- DoMarkedQualification(indexRelation, heapRelation, entry)
- Relation indexRelation;
- Relation heapRelation;
- ScanKeyEntry entry;
- {
- IndexScan scan;
- GeneralRetrieveIndexResult result;
- int tuplesLeft;
- bool markIsSet;
-
- tuplesLeft = MarkedTuplesToProcess;
- markIsSet = false;
-
- srandom((int)time(0));
-
- QualificationKeyData[0] = *entry;
-
- ShowScanKeyEntry(&QualificationKeyData[0]);
- puts("A MarkedQual scan of the index reveals...");
-
- scan = RelationGetIndexScan(indexRelation, 0x1 & random(), 1,
- (ScanKey)QualificationKeyData);
-
- while (tuplesLeft > 0) {
- if (!(random() & 0xf)) {
- printf("RESTARTING SCAN\n");
- IndexScanRestart(scan,
- 0x1 & random(),
- &QualificationKeyData[0]);
- markIsSet = false;
- }
- if (!(random() & 0x3)) {
- if (markIsSet) {
- printf("RESTORING MARK\n");
- IndexScanRestorePosition(scan);
- if (!(0x1 & random())) {
- markIsSet = false;
- }
- } else {
- printf("SET MARK\n");
- IndexScanMarkPosition(scan);
- markIsSet = true;
- }
- }
-
- result = IndexScanGetGeneralRetrieveIndexResult(scan, 0x1 & random());
- if (!GeneralRetrieveIndexResultIsValid(result)) {
- puts("\t*NULL*");
- } else {
- ShowResult(result, heapRelation);
- }
-
- tuplesLeft -= 1;
- }
- IndexScanEnd(scan);
- }
-
- /* ----------------------------------------------------------------
- * DoQualifiedScan
- * ----------------------------------------------------------------
- */
-
- void
- DoQualifiedScan(indexRelation, heapRelation, operation, flags, returnType)
- Relation indexRelation;
- Relation heapRelation;
- char *operation;
- uint16 flags;
- ObjectId returnType;
- {
- StrategyNumber strategyNumber;
- IndexStrategy indexStrategy;
- StrategyMap strategyMap;
- ScanKeyEntry scanKeyEntry;
-
- if (strcmp(operation, "<") == 0) {
- strategyNumber = BTreeLessThanStrategyNumber;
- } else if (strcmp(operation, "<=") == 0) {
- strategyNumber = BTreeLessThanOrEqualStrategyNumber;
- } else if (strcmp(operation, "=") == 0) {
- strategyNumber = BTreeEqualStrategyNumber;
- } else if (strcmp(operation, ">=") == 0) {
- strategyNumber = BTreeGreaterThanOrEqualStrategyNumber;
- } else if (strcmp(operation, ">") == 0) {
- strategyNumber = BTreeGreaterThanStrategyNumber;
- } else {
- fprintf(stderr, "testbtdel: unknown operation \"%s\"\n",
- operation);
- return;
- }
-
- indexStrategy = RelationGetIndexStrategy(indexRelation);
-
- strategyMap = IndexStrategyGetStrategyMap(indexStrategy,
- BTreeNumberOfStrategies, 1);
-
- scanKeyEntry = StrategyMapGetScanKeyEntry(strategyMap, strategyNumber);
-
- if (!RegProcedureIsValid(scanKeyEntry->procedure)) {
- fprintf(stderr, "testbtdel: no procedure for strategy %d\n",
- strategyNumber);
-
- return;
- }
-
- /*
- * Note: very dangerous to modify the reldesc, since it is cached.
- */
- scanKeyEntry->attributeNumber = 1;
- scanKeyEntry->flags = flags;
- scanKeyEntry->argument = ObjectIdGetDatum(returnType);
-
- switch (QualificationState) {
- case UninitializedQualification:
- case MarkedQualification:
- QualificationState = SingleQualification;
- DoSingleQualification(indexRelation, heapRelation,
- scanKeyEntry);
- break;
- case SingleQualification:
- QualificationState = DoubleQualification;
- DoDoubleQualification(indexRelation, heapRelation,
- scanKeyEntry);
- break;
- case DoubleQualification:
- QualificationState = MarkedQualification;
- DoMarkedQualification(indexRelation, heapRelation,
- scanKeyEntry);
- break;
- default:
- fprintf(stderr, "testbtdel: internal error!");
- exitpg(255);
- }
- }
-
- /* ----------------------------------------------------------------
- * TestMain
- * ----------------------------------------------------------------
- */
-
- void
- TestMain()
- {
- static NameData heapNameData;
- static NameData indexNameData;
- Relation indexRelation;
- Relation heapRelation;
- static int beenHere = 0;
- Portal portal;
-
-
- Relation AMopenr(); /* XXX */
-
-
- portal = CreatePortal("<blank>");
- StartTransactionCommand(portal);
-
- if (beenHere == 0) {
-
- /* discard any stuff on the input stream */
- fseek(stdin, 0, 2);
-
- puts("Please enter a heap relation name");
- if (scanf("%s", heapNameData.data) != 1) {
- elog(NOTICE, "testbtdel: no heap specified");
- exitpg(0);
- }
- puts("Please enter an index name");
- if (scanf("%s", indexNameData.data) != 1) {
- elog(NOTICE, "testbtdel: no index specified");
- exitpg(0);
- }
-
- puts("Please enter an attribute number to index");
- puts("If the relation is already indexed, enter");
- puts("the negative of the index attribute number");
- if (scanf("%hd", &indexAttrNumber) != 1) {
- elog(NOTICE, "testbtdel: attribute incorrectly specified");
- exitpg(0);
- }
-
- if (indexAttrNumber > 0) {
- puts("Please enter the operator class of the attribute");
- puts("--> hint: intops = 421 <--");
- if (scanf("%d", &indexAttrClass) != 1) {
- elog(NOTICE, "testbtdel: op class incorrectly specified");
- exitpg(0);
- }
-
- fseek(stdin, 0, 2);
-
- beenHere = 1;
-
- DoCreateIndex(&heapNameData, &indexNameData,
- indexAttrNumber, indexAttrClass);
-
- } else {
- indexAttrNumber = -indexAttrNumber;
- }
-
- CommitTransactionCommand();
- StartTransactionCommand(portal);
-
- beenHere = 2;
-
- } else if (beenHere == 1) {
- elog(NOTICE, "testbtdel: %s relation may exist--continuing!",
- indexNameData.data);
- beenHere = 2;
-
- } else if (beenHere > 1) {
- elog(FATAL, "testbtdel: giving up!");
- }
-
- QualificationState = UninitializedQualification;
-
- indexRelation = AMopenr(indexNameData.data);
- heapRelation = RelationNameOpenHeapRelation(heapNameData.data);
-
- DoBTreeBrowse(indexRelation, heapRelation);
-
- DoForwardScan(indexRelation, heapRelation);
-
- DoBackwardScan(indexRelation, heapRelation);
-
- for (;;) {
- int status;
- NameData operatorNameData;
- int flags;
- ObjectId returnType;
-
- puts("\nPlease enter an operator, flags, and an integer value");
-
- fseek(stdin, 0, 2); /* discard any stuff on the input stream */
- status = scanf("%s%d%d", &(operatorNameData), &flags,
- &returnType);
-
- if (status <= 0) {
- break;
- } else if (status != 3) {
- elog(NOTICE, "testbtdel: improper qualification specified");
- exitpg(0);
- }
-
- DoQualifiedScan(indexRelation, heapRelation, &operatorNameData,
- flags, returnType);
- }
-
- RelationCloseHeapRelation(heapRelation);
- RelationCloseIndexRelation(indexRelation);
-
- CommitTransactionCommand();
-
- puts("\nDone!");
- }
-